home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 7691 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.5 KB  |  108 lines

  1. Path: keats.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Checking For Keyboard Input
  5. Date: 26 Feb 1996 14:07:00 -0800
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4gtau4INNbtr@keats.ugrad.cs.ubc.ca>
  8. References: <cerebus.34.000DD98A@voicenet.com> <4gqriq$qf2@maureen.teleport.com> <3131EA31.167E@mozart.bme.ohio-state.edu>
  9. NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
  10.  
  11. In article <3131EA31.167E@mozart.bme.ohio-state.edu>,
  12. Xiaoyi Wu  <xiaoyi@mozart.bme.ohio-state.edu> wrote:
  13. >GHouck wrote:
  14. >> 
  15. >> cerebus@voicenet.com (aLEX) wrote:
  16. >> >Hello fellow C programmers,
  17. >> >        Is there anyway to check if keyboard input has been entered without
  18. >> >actually stalling the excution of the code until the user presses a key.  I
  19. >> >would really like to do this but I can't seem to find any way.  If you know of
  20. >> >a way PLEASE email me or post it.  Thank you in advance.
  21. >> >                                                    aLEX
  22. >> >                                                    cerebus@voicenet.com
  23. >> aLEX,
  24. >> There is if you're using Borland on DOS/Windows: there is a function called
  25. >>   kbhit()
  26. >> If a key has been hit, it returns a non-zero value, else it returns zero.  If
  27. >> one is available you can then get it with another call.
  28. >> Yours, Geoff Houck
  29. >
  30. >What about Unix?
  31.  
  32. You can write a UNIX kbhit() function, but it will require that some
  33. initialization and cleanup code be called. This is why the FAQ recommends that
  34. a properly written kbhit() will have a setup call and a cleanup call---on some
  35. systems, the terminal driver has to be configured for character-at-a-time mode.
  36.  
  37. The FAQ discusses the many good reasons why such functionality was not drafted
  38. into the standards.
  39.  
  40. In any case, a UNIX kbhit would just look like something like this, after
  41. appropriate setup of the terminal driver:
  42.  
  43.  
  44. #include <sys/time.h>
  45. #include <sys/types.h>
  46. #include <unistd.h>
  47. #include <fcntl.h>
  48.  
  49. int kbhit(void)
  50.  
  51. {
  52.     fd_set fds;        /* file descriptor set        */
  53.     struct timeval tv = {    /* timer value structure    */
  54.         0, 0        /* zero seconds, microseconds    */
  55.     };
  56.  
  57.     FD_ZERO(&fds);        /* clear file descriptor set    */
  58.     FD_SET(0,&fds);        /* add standard input to it    */
  59.  
  60.     return select(1,&fds,NULL,NULL,&tv);
  61. }
  62.  
  63. The select() function is used to test multiple descriptors for input, readiness
  64. to take output, or the presence of exception conditions. If you specify a
  65. zero-valued timeout structure, it effectuates a quick poll.
  66.  
  67. This code assumes that your terminal input is file descriptor 0, for clarity.
  68.  
  69. There are other ways to accomplish this. You can use a non-blocking read on the
  70. terminal. Or you can set up a special mode on the terminal that will allow you
  71. to check for characters. However, both these other methods will dequeue the
  72. character if it is available. select() will not cause any I/O to take place.
  73.  
  74.  
  75. The way you set up a terminal so that you can do the above for each keystroke
  76. is:
  77.  
  78. #include <termio.h>
  79.  
  80. static struct termios save;
  81.  
  82. void rawmode(void)        /* set up raw behavior on terminal    */
  83. {
  84.     struct termios change;
  85.  
  86.     tcgetattr(0, &change);    /* get attributes of terminal device    */
  87.                 /* assumes fd 0 is a terminal :( bad!    */
  88.  
  89.     save = change;        /* save previous settings        */
  90.  
  91.     /*
  92.      * code to change the settings in the ``change structure''
  93.      */
  94.  
  95.     tcsetattr(0, TCSAFLUSH, &change);
  96. }
  97.  
  98. void restore(void)        /* restore terminal            */
  99. {
  100.     tcsetattr(0, TCSAFLUSH, &save);
  101. }
  102.  
  103.  
  104. The ``code to change the settings'' is probably found in the FAQ. I don't want
  105. to get into it. Get a book!
  106. -- 
  107.  
  108.